package com.dlc.shop.api.controller;


import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.dlc.shop.bean.app.param.PayUserParam;
import com.dlc.shop.bean.enums.PayEntry;
import com.dlc.shop.bean.model.UserExtension;
import com.dlc.shop.bean.pay.PayInfoDto;
import com.dlc.shop.common.allinpay.constant.AllinpayConstant;
import com.dlc.shop.common.allinpay.constant.PaySysType;
import com.dlc.shop.common.bean.PaySettlementConfig;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.constants.SegmentIdKey;
import com.dlc.shop.common.enums.PayType;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.Arith;
import com.dlc.shop.manager.impl.PayManager;
import com.dlc.shop.security.api.util.SecurityUtils;
import com.dlc.shop.security.common.bo.LoginInfoBO;
import com.dlc.shop.security.common.manager.TokenStore;
import com.dlc.shop.security.common.util.AuthUserContext;
import com.dlc.shop.service.PayInfoService;
import com.dlc.shop.service.SegmentService;
import com.dlc.shop.service.SysConfigService;
import com.dlc.shop.service.UserExtensionService;
import com.dlc.shop.user.common.model.UserBalance;
import com.dlc.shop.user.common.model.UserBalanceLog;
import com.dlc.shop.user.common.service.UserBalanceLogService;
import com.dlc.shop.user.common.service.UserBalanceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Objects;

/**
 * @author LHD on 2020/03/02.
 */
@Tag(name = "余额支付接口")
@RestController
@RequestMapping("/p/balance")
@AllArgsConstructor
public class PayBalanceController {

    /**
     * 会员信息
     */
    private final UserBalanceService userBalanceService;
    private final UserBalanceLogService userBalanceLogService;
    private final UserExtensionService userExtensionService;
    private final SegmentService segmentService;
    private final PayManager payManager;
    private final PayInfoService payInfoService;
    private final SysConfigService sysConfigService;
    private final TokenStore tokenStore;

    /**
     * 会员余额充值接口
     */
    @PostMapping("/pay")
    @Operation(summary = "会员余额充值" , description = "会员余额充值")
    @SneakyThrows({WxPayException.class, AlipayApiException.class})
    public ServerResponseEntity<?> payVip(HttpServletResponse httpResponse, @RequestBody PayUserParam payCardParam) {
        String userId = AuthUserContext.getUserId();
        if (payCardParam.getPayType().equals(PayType.SCOREPAY.value()) || payCardParam.getPayType().equals(PayType.BALANCE.value())){
            // 请使用微信或支付宝进行支付
            throw new YamiShopBindException("yami.user.payType.error");
        }
        // 查询支付系统类型
        PaySettlementConfig config = sysConfigService.getSysConfigObject(Constant.PAY_SETTLEMENT_CONFIG, PaySettlementConfig.class);
        Integer paySysType = config.getPaySettlementType();
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        UserBalance userBalance = null;
        double balance;
        if (Objects.equals(paySysType, PaySysType.ALLINPAY.value())) {
            balance = userExtension.getAllinpayTotalBalance();
        } else {
            balance = userExtension.getTotalBalance();
        }
        // 计算总实际余额
        if (Objects.equals(payCardParam.getId(), -1L)) {
            // 自定义金额
            balance = Arith.add(balance, payCardParam.getCustomRechargeAmount());
        } else {
            // 购买
            userBalance = userBalanceService.getById(payCardParam.getId());
            if (Objects.isNull(userBalance)) {
                // 当前余额充值选项已被删除
                throw new YamiShopBindException("yami.user.blance.not.exist");
            }
            balance = Arith.add(balance, userBalance.getRechargeAmount());
        }
        if (balance > Constant.MAX_USER_BALANCE) {
            // 您的余额加充值的余额将大于最大余额，不能进行充值操作
            throw new YamiShopBindException("yami.balance.than.max.balance");
        }
        // 使用leaf算法生成支付单号
        String payNo = String.valueOf(segmentService.getDateFormatSegmentId(SegmentIdKey.PAY));
        Date now = new Date();
        //生成余额充值日志
        UserBalanceLog userBalanceLog = new UserBalanceLog();
        userBalanceLog.setCreateTime(now);
        userBalanceLog.setIoType(1);
        userBalanceLog.setType(1);
        userBalanceLog.setIsPayed(0);
        userBalanceLog.setPayNo(payNo);
        userBalanceLog.setUserId(userId);
        userBalanceLog.setPaySysType(paySysType);
        if (Objects.equals(payCardParam.getId(), -1L)) {
            userBalanceLog.setBalanceId(-1L);
            userBalanceLog.setChangeBalance(payCardParam.getCustomRechargeAmount());
        } else {
            userBalanceLog.setBalanceId(userBalance.getBalanceId());
            userBalanceLog.setChangeBalance(userBalance.getRechargeAmount());
        }
        userBalanceLogService.save(userBalanceLog);
        payCardParam.setNeedAmount(userBalanceLog.getChangeBalance());
        payCardParam.setPayNo(payNo);
        payCardParam.setOrderIds(userBalanceLog.getBalanceLogId());
        PayInfoDto payInfo = payInfoService.recharge(userId, payCardParam,paySysType);

        LoginInfoBO loginInfo = tokenStore.getLoginInfoByCache();
        if (loginInfo!=null) {
            payInfo.setBizUserId(loginInfo.getBizUserId());
        }


        payInfo.setAllinpayUserId(AllinpayConstant.USER + userId);
        payInfo.setPayType(payCardParam.getPayType());
        payInfo.setApiNoticeUrl("/notice/pay/" + paySysType + "/" + PayEntry.RECHARGE.value() + "/" + payCardParam.getPayType());
        payInfo.setReturnUrl(payCardParam.getReturnUrl());
        payInfo.setPaySysType(paySysType);
        payInfo.setSystemType(payCardParam.getSystemType());
        payInfo.setValidateType(payCardParam.getValidateType());
        payInfo.setUserId(userId);
        return payManager.doPay(httpResponse, payInfo);
    }

    @GetMapping("/isPay")
    @Operation(summary = "获取余额充值支付信息" , description = "获取余额充值支付信息")
    public ServerResponseEntity<Integer> isPay(){
        String userId = SecurityUtils.getUser().getUserId();
        PaySettlementConfig config = sysConfigService.getSysConfigObject(Constant.PAY_SETTLEMENT_CONFIG, PaySettlementConfig.class);
        UserBalanceLog userBalanceLog = userBalanceLogService.getMaxCrtTimeByUserId(userId, config.getPaySettlementType());
        return ServerResponseEntity.success(userBalanceLog.getIsPayed());
    }

}
